package com.example.behaviorpattern.visitor;

import com.example.behaviorpattern.visitor.impl.ConcreteElementA;
import com.example.behaviorpattern.visitor.impl.ConcreteElementB;
import com.example.behaviorpattern.visitor.impl.ConcreteVisitorA;
import com.example.behaviorpattern.visitor.impl.ConcreteVisitorB;

/**
 * 访问者模式是一种行为型设计模式
 * 它将数据结构和作用于结构上的操作解耦，使得操作集合可以在不修改数据结构的情况下定义新的操作。
 * 这个模式是对对象结构中不同类的元素提出不同的访问接口，从而允许在不修改类的前提下，定义作用于这些元素的新操作。
 * 访问者模式适用于以下场景：
 * 当一个数据结构包含很多不同类的对象，且你希望对这些对象执行一些不相关的操作时，可以使用访问者模式，这样可以避免这些操作“污染”这些对象的类。
 * 需要在不同的对象集合之间定义操作，并且希望使用同一操作集合避免代码重复时。
 * 当类库中的对象结构很少改变，但经常需要在此结构上定义新的操作时。
 * 访问者模式通常包含以下组件：
 * Visitor：接口或抽象类，定义了访问者可以访问的对象接口。
 * ConcreteVisitor：实现Visitor接口的具体类，定义了对每个元素进行的具体操作。
 * Element：接口或抽象类，定义一个accept方法，该方法接受一个访问者对象。
 * ConcreteElement：实现Element接口的具体类，必须有一个accept方法。
 * ObjectStructure：拥有许多元素（Element），可以迭代这些元素并允许访问者访问它们。
 *
 * @author yaojianfeng
 */
public class VisitorTest {
    public static void main(String[] args) {
        // 创建对象结构
        ObjectStructure objectStructure = new ObjectStructure();
        // 添加对象元素
        objectStructure.attach(new ConcreteElementA("elementA", 10));
        objectStructure.attach(new ConcreteElementB("elementB", 20));
        //创建观察者
        ConcreteVisitorA visitorA = new ConcreteVisitorA();
        ConcreteVisitorB visitorB = new ConcreteVisitorB();

        // 遍历对象结构，并调用观察者的visit方法
        System.out.println("visitorA visit:===> ");
        objectStructure.visitElements(visitorA);
        System.out.println("visitorB visit:======> ");
        objectStructure.visitElements(visitorB);
    }
}
